;; =========================================================
;; 英文单词补全支持
;; 
;; * 依懒于 auto-complete，使用前自己安装一下
;; 
;; * 依赖于 dictfind 这个外部程序，请自己把
;;   dictfind 这个程序放在 $PATH 中。
;;   my-dict-path 为词典的位置，请自行修改
;; 
;; * 使用方法
;;   > 把 my-word-complete.el 放在相应目录，如果这个
;;     目录不在 load-path 中，那么把这个目录加一加
;;     如: (add-to-list 'load-path "你的目录")
;; 
;;   > 在 .emacs 中加入 (require 'my-word-complete)
;; 
;;   > 按键绑定 (global-set-key "\M-w" 'my-word-complete)
;; 
;; * 使用愉快
;; =========================================================

;; 网上抄的: 字符串去掉空白
(defun my-chomp (str)
  "Chomp leading and tailing whitespace from STR."
  (let ((s (if (symbolp str) (symbol-name str) str)))
    (replace-regexp-in-string "\\(^[[:space:]\n]*\\|[[:space:]\n]*$\\)" "" s)))

;; 英文单词放在哪里
(setq my-dict-path
      (expand-file-name "~/dict.dat"))

(defun my-ac-word-candidate ()
  (let ((incomplete-word ac-prefix) (maybes) (line)
        (selection) (comp-failed nil))
    (when incomplete-word
      (with-temp-buffer
        (if (not (= 0 (call-process "dictfind" nil t nil "-d" my-dict-path
                                    "-n" (int-to-string (if ac-limit ac-limit 20))
                                    incomplete-word)))
            ;; dictfind return failed code
            ;; show the error message to user
            (progn (setq comp-failed t)
                   (message "dictfind complete word failed: %s"
                            (buffer-substring-no-properties
                             (point-min) (point-max))))
          ;; word line by line
          (goto-char (point-min))
          (while (not (eobp))
            (setq line (my-chomp (thing-at-point 'line)))
            (when (> (length line) 0)
              (push line maybes))
            (forward-line 1))))

      (when (> (length maybes) 0)
        (setq maybes (reverse maybes)))

      maybes)))

(defun my-find-word-meaning (symbol)
  (when (stringp symbol)
    (with-temp-buffer
      (ignore-errors
        (call-process "sdcv" nil t nil "-n" symbol))
      (buffer-substring-no-properties
       (point-min) (point-max)))))

;; 用 auto-complete 去补全
;; \= 表示仅在当前点
(defvar my-ac-source-word
  '((candidates . my-ac-word-candidate)
    (prefix     . "\\<[a-zA-Z]+")
    (document   . my-find-word-meaning)
    (symbol     . "d"))
  "Source for word complete.")

(defun my-word-complete ()
  (interactive)
  (let ((bak ac-sources))
    (unwind-protect
        (progn (setq ac-sources '(my-ac-source-word))
               (auto-complete)
               (setq ac-sources bak))
      (setq ac-sources bak))))

(provide 'my-word-complete)
